package com.dyz.leetcode._12_linkedList;

import com.dyz.leetcode.ListNode;

import java.util.ArrayDeque;

public class _445_addTwoNumbers {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        l1 = reverse(l1);
        l2 = reverse(l2);
        ListNode res = addTwoNumbers1(l1, l2);
        return reverse(res);
    }

    public ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
        int carry = 0;
        ListNode dummy = new ListNode(-1);
        ListNode curr = dummy;
        while(l1!=null || l2!=null){
            int x = l1==null?0:l1.val;
            l1 = l1==null?null:l1.next;
            int y = l2==null?0:l2.val;
            l2 = l2==null?null:l2.next;

            int sum = x+y+carry;
            carry = sum/10;
            curr.next = new ListNode(sum%10);
            curr = curr.next;
        }
        //  最后一位
        if(carry!=0){
            curr.next = new ListNode(carry);
        }
        return dummy.next;
    }

    private ListNode reverse(ListNode head){
        ListNode prev = null;
        ListNode curr = head;
        while (curr!=null){
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }

    // 使用栈
    public ListNode addTwoNumbers2(ListNode l1, ListNode l2) {
        if (l1 == null) {return l2;}
        if (l2 == null) {return l1;}

        // 将 l1 所有节点放到栈中
        ArrayDeque<ListNode> stack1 = new ArrayDeque<>();
        while (l1 != null) {
            stack1.push(l1);
            l1 = l1.next;
        }
        // 将 l2 所有节点放到栈中
        ArrayDeque<ListNode> stack2 = new ArrayDeque<>();
        while (l2 != null) {
            stack2.push(l2);
            l2 = l2.next;
        }

        ListNode ans = null;
        // 用于存储两数相加时的进位
        int carry = 0;
        while (!stack1.isEmpty() || !stack2.isEmpty()) {
            int x = stack1.isEmpty() ? 0 : stack1.pop().val;
            int y = stack2.isEmpty() ? 0 : stack2.pop().val;

            int sum = x + y + carry;

            ListNode curr = new ListNode(sum % 10);
            curr.next = ans;
            ans = curr;

            carry = sum / 10;
        }

        if (carry != 0) {
            ListNode curr = new ListNode(carry);
            curr.next = ans;
            ans = curr;
        }

        return ans;
    }
}
